热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

都会|患者_Swift两种方式实现async/await并发模型中任务超时(timeout)的取消

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Swift两种方式实现async/await并发模型中任务超时(timeout)的取消相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Swift 两种方式实现 async/await 并发模型中任务超时(timeout)的取消相关的知识,希望对你有一定的参考价值。



文章目录


  • 1. 概览
  • 2. Task 超时取消实现之思路
  • 3. 第一种实现
  • 4. 第二种实现
  • 5. 总结


1. 概览

从 Swift 5.5 开始,Apple 引入了新的 async/await 并发模型,我们可以利用它很方便的开发结构化并发代码。

在使用新的并发模型时,一个常见的需求就是任务超时的处理。

我们希望当耗时任务的执行在到达指定时间后自动取消,以免影响用户体验。

在本篇博文中,我们将用两种方法来实现新并发模型中 Task 执行的超时处理。

废话少叙,Let’s Go!!!😉




2. Task 超时取消实现之思路

在 Swift 新 async/await 并发模型中,每个 Task 都会并发执行。所以,要想实现任务超时处理我们只需要同时执行两个任务:


  1. 第一个是需要完成的任务;
  2. 第二个是超时监控任务,用它来监听第一个任务是否已超时,如果是则果断取消它;

有的小伙伴可能觉得实现监控任务有点棘手,其实,这超乎意料的简单!


3. 第一种实现

我们只需保存执行的 Task 对象,然后在超时发生时,在第二个超时监控任务中将其取消即可,代码如下:

struct TimedOutError: Error, Equatable
func execute<R>(timeout: TimeInterval, task: &#64;escaping () async throws -> R) async throws -> R

let task &#61; Task
try await task()


Task
try? await Task.sleep(until: .now &#43; .seconds(timeout), clock: .continuous)
task.cancel()


do
return try await task.value
catch
// 如果任务被取消&#xff0c;则我们知道任务超时了
if task.isCancelled
throw TimedOutError()

throw error


正如之前的实现思路&#xff0c;我们依次创建了两个任务&#xff1a;第一个是需要完成的任务&#xff0c;第二个则是超时监控任务&#xff1b;在第二个任务中&#xff0c;一旦超时到达&#xff0c;则取消第一个任务。

Task
do
let r &#61; try await execute(timeout: 3.0)
// 任务会触发超时&#xff0c;将被取消&#xff01;
try await Task.sleep(until: .now &#43; .seconds(3.1), clock: .continuous)
return 11


print("结果是 \\(r)")
catch
print("ERR: \\(error.localizedDescription)")


不过&#xff0c;这样有两个小问题&#xff1a;


  1. 如果第一个任务在超时前完成&#xff0c;超时监控任务在超时后仍会尝试取消它&#xff1b;
  2. 当任务执行出现异常时&#xff0c;我们需要判断任务是否被取消&#xff0c;然后再抛出 TimedOutError 错误&#xff1b;

虽然&#xff0c;这并不影响整个 execute() 方法的逻辑&#xff0c;但如果小伙伴们是强迫症患者&#xff0c;我们还有第二种方法可以选择。


4. 第二种实现

第二种方法和前者类似&#xff0c;不过这里我们利用了新并发模型中任务组&#xff08;TaskGroup&#xff09;的特点&#xff1a;其中所有子任务都会并发执行&#xff0c;而且我们可以取消所有子任务。

func execute2<R>(timeout: TimeInterval, task: &#64;escaping () async throws -> R) async throws -> R
try await withThrowingTaskGroup(of: R.self) group in
group.addTask
try await task()


group.addTask
try await Task.sleep(until: .now &#43; .seconds(timeout), clock: .continuous)
throw TimedOutError()


let result &#61; try await group.next()!
// 一旦我们取消所有子任务&#xff0c;则超时监控任务不会在正常任务未超时还抛出异常
group.cancelAll()
return result


如上代码所示&#xff0c;用 TaskGroup 来实现任务超时逻辑更加清晰&#xff0c;而且避免了第一种方法中的两个问题。



更多 Task 任务超时的讨论请参考下面的链接&#xff1a;

Running an async task with a timeout




5. 总结

在本篇博文中&#xff0c;我们用两种方法实现了 Swift 新 async/await 并发模型中任务超时的取消&#xff0c;任君选择。

感谢观赏&#xff0c;再会&#xff01;&#x1f60e;


推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • Iamtryingtocreateanarrayofstructinstanceslikethis:我试图创建一个这样的struct实例数组:letinstallers: ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 设计模式——模板方法模式的应用和优缺点
    本文介绍了设计模式中的模板方法模式,包括其定义、应用、优点、缺点和使用场景。模板方法模式是一种基于继承的代码复用技术,通过将复杂流程的实现步骤封装在基本方法中,并在抽象父类中定义模板方法的执行次序,子类可以覆盖某些步骤,实现相同的算法框架的不同功能。该模式在软件开发中具有广泛的应用价值。 ... [详细]
  • 本文介绍了一种图的存储和遍历方法——链式前向星法,该方法在存储带边权的图时时间效率比vector略高且节省空间。然而,链式前向星法存图的最大问题是对一个点的出边进行排序去重不容易,但在平行边无所谓的情况下选择这个方法是非常明智的。文章还提及了图中搜索树的父子关系一般不是很重要,同时给出了相应的代码示例。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • Java编程实现邻接矩阵表示稠密图的方法及实现类介绍
    本文介绍了Java编程如何实现邻接矩阵表示稠密图的方法,通过一个名为AMWGraph.java的类来构造邻接矩阵表示的图,并提供了插入结点、插入边、获取邻接结点等功能。通过使用二维数组来表示结点之间的关系,并通过元素的值来表示权值的大小,实现了稠密图的表示和操作。对于对稠密图的表示和操作感兴趣的读者可以参考本文。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
author-avatar
淘气小顽童刘
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有